package com.shiguiwu.springmybatis.spring.transaction.propagation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.w3c.dom.ls.LSOutput;

/**
 * @description:
 * @author: stone
 * @date: Created by 2021/6/15 9:50
 * @version: 1.0.0
 * @pakeage: com.shiguiwu.springmybatis.spring.transaction.propagation
 */
@Service
public class TxService3 {


    @Autowired
    private TxService1 txService1;

    @Autowired
    private TxService2 txService2;

    public void notransaction_exception_required_required() throws Exception {
        //http://124.70.98.107:8090/riskcensus/app/onlineUpdate.json
//        jdbcTemplate.update("insert into book(book_name) values (?)", bookName);
        txService1.required("西游记");
        txService2.required_exception("三国演义");
//        throw new RuntimeException(".....");
    }

    @Transactional
    public void transaction_exception_required_required() throws Exception {
        //http://124.70.98.107:8090/riskcensus/app/onlineUpdate.json
//        jdbcTemplate.update("insert into book(book_name) values (?)", bookName);
        txService1.required("西游记");
        txService2.required("三国演义");
//        throw new RuntimeException(".....");
    }


    @Transactional
    public void transaction_exception_try_required_required() throws Exception {
        //http://124.70.98.107:8090/riskcensus/app/onlineUpdate.json
//        jdbcTemplate.update("insert into book(book_name) values (?)", bookName);
        txService1.required("西游记");
        try {
            txService2.required_exception("三国演义");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("异常。。。。");
        }
//        throw new RuntimeException(".....");
    }

    /**
     *  不影响，成功插入
     */
    public void notransaction_exception_requiresNew_requiresNew() {
        txService1.required_new("红楼梦");
        txService2.required_new("水浒传");
        throw new RuntimeException("aaaa");
    }

    public void notransaction_exception_requiresNew_requiresNew2() throws Exception {
        txService1.required_new("红楼梦");
        txService2.required_new_exception("水浒传");
//        throw new RuntimeException("aaaa");
    }


    /**
     * 在外围方法开启事务的情况下 Propagation.REQUIRES_NEW 修饰的内部方法依然会单独开启独立事
     * 务，且与外部方法事务也独立，内部方法之间、内部方法和外部方法事务均相互独立，互不干扰。
     * @throws Exception
     */
    @Transactional
    public void transaction_exception_requiresNew_requiresNew() throws Exception {
        txService1.required("西游记");
        txService1.required_new("红楼梦");
        txService2.required_new_exception("水浒传");
        throw new RuntimeException("aaaa");
    }

    /**
     * 通过这两个方法我们证明了在外围方法未开启事务的情况下 Propagation.NESTED 和
     * Propagation.REQUIRED 作用相同，修饰的内部方法都会新开启自己的事务，且开启的事务相互独
     * 立，互不干扰。
     */

//    @Transactional
    public void notransaction_exception_nested() throws Exception {
        txService1.nested("西游记");
        txService2.nested("红楼梦");
//        txService2.required_new_exception("水浒传");
        throw new RuntimeException("aaaa");
    }

    /**
     * 外围方法开启事务，内部事务为外围事务的子事务，外围方法回滚，
     * 内部方法也要回滚。
     * @throws Exception
     */
    @Transactional
    public void transaction_exception_nested() throws Exception {
        txService1.nested("西游记");
        txService2.nested_exception("红楼梦");
    }

    @Transactional(propagation = Propagation.NESTED)
    public void transaction_exception_nestedx() throws Exception {
        txService1.nested("西游记");
        txService2.nested_exception("红楼梦");
    }


}
